<template>
	<view class="content">
		<button class="mini-btn" type="primary" size="mini" @click="uploadFiles('moives')">上传视频</button>

		<!-- 上传进度列表 -->
		<view class="list-item" v-for="item in taskList" :key="item.key">
			<view class="list-right">
				<view>{{ item.title }}</view>
				<view>{{ item.percent }}</view>
				<progress :percent="getProgress(item)" :show-info="true" stroke-width="3" />
				<button class="mini-btn" type="primary" size="mini" @click="pause(item)">{{ item.pause ? '继续' : '暂停' }}</button>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			bytesPerPiece: 1024 * 1024, // 每个文件切片大小定为4MB .
			taskList: [] // 上传的列表
		};
	},
	onLoad() {
		console.log('页面首次加载');
	},
	methods: {
		async stop() {
			if (this.uploadTask !== '') {
				this.uploadTask.abort();
			}
		},

		/**
		 * @param {Object} type 文件的类型
		 */
		async uploadFiles(type) {
			let uploadType = '';
			switch (type) {
				case 'moives':
					uploadType = 'checkMoives';
					break;
				case 'music':
					uploadType = 'checkMusic';
					break;
				case 'photos':
					uploadType = 'checkPhotos';
					break;
				case 'document':
					uploadType = 'checkDocument';
					break;
				default:
					break;
			}
			// 引入原生插件进行上传
			const CheckMobileContent = uni.requireNativePlugin('CheckMobileContent');
			try {
				CheckMobileContent[uploadType](
					{
						fileNum: 10 //限制的数量，不能超过这个数量
					},
					res => {
						// 上传的回调函数，处理返回的文件
						uni.removeStorageSync('totalSliceTask');
						this.dealFiles(res, type);
					}
				);
			} catch (e) {
				// 上传失败
				uni.showToast({
					title: '上传失败 ' + e + CheckMobileContent,
					icon: 'none'
				});
			}
		},

		/**
		 * 处理选择的文件
		 * @param {Object} data 选择文件后的临时地址等信息
		 * @param {Object} type 文件的类型
		 */
		async dealFiles({ data }, type) {
			if (type === 'moives') {
				// 1、处理上传的视频
				console.log(data, 'data');
				JSON.parse(data).forEach((val, index) => {
					const { path: tempFilePath, name: title } = val;
					// console.log('临时的文件地址', tempFilePath);
					// 对文件进行切片
					this.sliceFiles(tempFilePath, title, index);
				});
			}
		},

		/**
		 * 文件进行切片处理
		 * @param {Object} tempFilePath 文件的临时地址
		 * @param {Object} title 文件名称
		 */
		sliceFiles(tempFilePath, title, type) {
			console.log('sliceFiles');
			if (tempFilePath.indexOf('_doc') != -1) {
				tempFilePath = plus.io.convertLocalFileSystemURL(tempFilePath); // 将本地URL路径转换成平台绝对路径
			} else {
				tempFilePath = tempFilePath.replace('file://', '');
			}
			const KJFileSlice = uni.requireNativePlugin('KJ-FileSlice');
			var dic = {
				pathFileName: tempFilePath,
				savePath: plus.io.convertLocalFileSystemURL('_doc/KJ-FileSlice'), //保存切片地址，一定要是_doc目录
				sliceSize: this.bytesPerPiece, //切片大小，单位（B）
				sliceSuffixName: '' //保存切片的后缀名
			};
			KJFileSlice.start(dic, res => {
				// 生成一个随机的待上传的切片任务key值
				const taskId = this.uuid2(8, 8);
				// 先判断缓存里面是否有待上传的切片任务
				const totalSliceTask = uni.getStorageSync('totalSliceTask');
				if (totalSliceTask) {
					// 1、已经存在等待上传的切片任务
					const totalSliceTaskArr = JSON.parse(totalSliceTask);
					// 2、totalSliceTaskArr中再次添加本次的切片结果
					totalSliceTaskArr.push({
						key: taskId,
						title: title,
						percent: 0, // 进度
						totalPieces: res.slices.length, // 总切片数
						pause: false, // 是否暂停该任务
						content: res.slices
					});
					// 存储到缓存
					uni.setStorageSync('totalSliceTask', JSON.stringify(totalSliceTaskArr));
					// 开始上传切片
					// this.apiUploadFiles(res.slices);
				} else {
					// 2、不存在等待上传的切片任务，即不存在key值totalSliceTask,生成一个随机的待上传的切片任务key值
					const totalSliceTaskArr = [];
					totalSliceTaskArr.push({
						key: taskId,
						title: title,
						percent: 0, // 进度
						totalPieces: res.slices.length, // 总切片数
						pause: false, // 是否暂停该任务
						content: res.slices
					});
					// 存储到缓存
					console.log(totalSliceTaskArr, 'totalSliceTaskArr');
					uni.setStorageSync('totalSliceTask', JSON.stringify(totalSliceTaskArr));
					// 开始上传切片
					// this.apiUploadFiles(res.slices);
				}
				this.apiUploadFiles({
					key: taskId,
					title: title,
					percent: 0, // 进度
					totalPieces: res.slices.length, // 总切片数
					pause: false, // 是否暂停该任务
					content: res.slices
				});
			});
		},

		/**
		 * 上传的数据处理
		 * @param {Object} taskId 需要上传的任务id
		 * @param {Object} callBack 执行完成后的回调函数
		 */
		async apiUploadFiles(taskObj) {
			this.taskList = JSON.parse(uni.getStorageSync('totalSliceTask'));
			// 取出缓存中的这个任务id对应的切片内容，进行上传
			for (let i = taskObj.percent; i < taskObj.content.length; i++) {
				// console.log(taskList.content.length, '长度');
				// 暂停下载
				if (taskObj.pause) return;
				const content = taskObj.content[i];
				const formData = {
					fileName: taskObj.title,
					offset: this.bytesPerPiece * i,
					directory: '/'
				};
				const res = await this.addFile(content, formData);
				console.log(i, '上传成功');
				if (res) {
					// 更新缓存里的数据
					taskObj.percent = i+1;
					let index = this.taskList.findIndex(pre => pre.key === taskObj.key);
					this.taskList[index] = taskObj;
					// 更新页面的数据
					this.$forceUpdate();
					uni.setStorageSync('totalSliceTask', JSON.stringify(this.taskList));
					// 上传成功
				}
			}
			console.log(this.taskList, 'this.taskList');
		},

		/**
		 * @param {Object} content 上传组件需要的参数
		 * @param {Object} formData 需要传给后台的参数
		 */
		addFile(content, formData) {
			// console.log('开始上传content', content);
			// console.log('开始上传formData', formData);
			return new Promise((resolve, reject) => {
				uni.uploadFile({
					url: 'http://58.34.36.138:18480/nasforward/file/upload?uploadToken=NAS_UPLOAD_51f196c792f06d72649e627df0dad23b',
					filePath: content.filePath,
					formData: formData,
					name: 'content',
					// header: {
					// 	'Content-Type': 'multipart/form-data'
					// },
					success: res => {
						resolve(res);
					},
					fail: err => {
						console.log(err, '上传失败');
					}
				});
			});
		},

		// 暂停下载
		pause(item) {
			item.pause = !item.pause;
			if (!item.pause) {
				// 重新开启下载
				this.apiUploadFiles(item);
			}
		},
		// 计算进度
		getProgress(item) {
			return Math.floor((item.percent / item.totalPieces) * 100);
		},
		// 生成随机数，指定长度和基数
		uuid2(len, radix) {
			let chars = 'GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
			let uuid = [],
				i;
			radix = radix || chars.length;
			if (len) {
				// Compact form
				for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
			} else {
				let r = null;
				uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
				uuid[14] = '4';
				for (i = 0; i < 36; i++) {
					if (!uuid[i]) {
						r = 0 | (Math.random() * 16);
						uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
					}
				}
			}
			return uuid.join('');
		}
	}
};
</script>

<style lang="scss" scoped>
.content {
	width: 100%;
	.list-item {
		display: flex;
		.list-right {
			width: 300px;
		}
	}
}
</style>
